<script>
import { setStyle, addClass } from '@/common/js/dom'

const FRAME = 100

export default {
  name: 'Evolve',
  data() {
    return {
      sum: 0,
      currentNum: 0
    }
  },
  render: function(h) {
    return h(this.tag, {
      style: {
        transitionDuration: this.duration + 'ms'
      },
      class: {
        transition: true
      },
      ref: 'el'
    }, this.currentNum)
  },
  props: {
    min: {
      type: Number | String,
      default: 0
    },
    max: {
      type: Number | String,
      default: 100
    },
    tag: {
      type: String,
      default: 'span'
    },
    duration: {
      type: Number,
      default: 2000
    },
    endStyle: {
      type: Object,
      default: () => {}
    },
    endClass: {
      type: ''
    }
  },
  mounted() {
    this.start()
  },
  methods: {
    start() {
      this.stop()
      // 跳动次数
      const f = this.duration / FRAME

      const reg = /^(\d+)(\D*)$/
      const _matchMax = this.max.toString().match(reg)
      const _matchMin = this.min.toString().match(reg)
      const max = parseInt(_matchMax[1])
      const min = parseInt(_matchMin[1])
      const char = _matchMax[2] || _matchMin[2]

      // 每次应加数
      const oneNub = (max - min) / f

      setTimeout(() => {
        setStyle(this.$refs.el, this.endStyle)
        addClass(this.$refs.el, this.endClass)
      }, 1)

      this.$emit('begin')
      this.interval = setInterval(() => {
        this.sum++
        this.currentNum = `${(oneNub * this.sum) | 0}${char}`

        if (this.sum === f) {
          this.stop()
        }
        this.$emit('progress', { sum: this.sum, f })
      }, FRAME)
    },
    stop() {
      if (this.interval) {
        clearInterval(this.interval)
        this.$emit('complete')
      }
    }
  },
  watch: {
    min: {
      handler: function(newM, oldM) {
        if (newM === oldM) {
          return false
        }
        this.currentNum = newM
      },
      immediate: true
    }
  }
}
</script>

<style lang="stylus" scoped>
.transition
  transition: all 2s ease-out
</style>
